Operadores a nivel de bit (bitwise operators)
-----------------------------------------------------------------------------------------------------------------------------





-----------------------------------------------------------------------------------------------------------------------------
El operador AND "&" compara dos bits; si los dos son 1 el resultado es 1, en otro caso el resultado ser 0. 
Ejemplo:

        c1 = 0x45      --> 01000101
        c2 = 0x71      --> 01110001
        ---------------------------
        c1 & c2 = 0x41 --> 01000001





-----------------------------------------------------------------------------------------------------------------------------
El operador OR  "|" compara dos bits; si cualquiera de los dos bits es 1, entonces el resultado es 1; en otro caso ser 0. Ejemplo:

        i1 = 0x47      --> 01000111
        i2 = 0x53      --> 01010011
        ---------------------------
        i1 | i2 = 0x57 --> 01010111






-----------------------------------------------------------------------------------------------------------------------------

El operador exclusivo (XOR) "^", da por resultado uno cuando los dos operandos tienen distinto valor.


Cuando los dos operandos son distintos da 1.-
ej: 1 y 0    =1
    0 y 1    =1

Cuando los dos operandos son iguales da 0.-
    0 y 0    =0
    1 y 1    =0

 Ejemplo:

        i1 = 0x47      --> 01000111
        i2 = 0x53      --> 01010011
        ---------------------------
        i1 ^ i2 = 0x14 --> 00010100





-----------------------------------------------------------------------------------------------------------------------------
El operador de complemento a 1 "~" cambia cada dgito del operando por su opuesto:

si el bit es 1 se cambia por 0 y viceversa


        c = 0x45  --> 01000101
        ----------------------
        ~c = 0xBA --> 10111010




-----------------------------------------------------------------------------------------------------------------------------
Los operadores de desplazamiento a nivel de bit "<<" y ">>" Desplazan a la izquierda o a la derecha un nmero especificado de bits. 
En un desplazamiento a la izquierda los bits que sobran por el lado izquierdo se descartan y se rellenan los nuevos espacios con ceros. De manera anloga pasa con los desplazamientos a la derecha. Veamos un ejemplo:

 	c = 0x1C 	00011100

c << 1 	c = 0x38 	00111000
c >> 2 	c = 0x07 	00000111

Como en binario se trabaja en base dos cada posicin de desplazamiento implica dividir o multiplicar por 2

>> divide por 2. 

<< multiplica por 2

	c = 0x1C 	00011100

c << 1 	c = 0x38 	00111000 multiplica por 2
c >> 2 	c = 0x07 	00000111 divide 2 veces por 2 (divide por 4)








Dependiendo el compilador El operador shift   >> tiene diferente comportamiento 
--------------------------------------------------------------------------------
depende del tipo de dato al que se le va a aplicar. Ms precisamente si la variable fue creada con signo o sin signo.


EJEMPLO:
creamos dos variables

unsigned char A=100;
signed char B=-100;




Valor de A= 100 // valor decimal
Valor de A en binario: 01100100
Valor de A en binario luego de aplicarle shift >> 2:
Valor en binario:      00011001 // en este caso el bit ms significativo se indica con un cero.
                                //  y los bits que se desplacen hacia la derecha del bit ms significativo 
                                // se completan con ceros 0.

Valor de B= -100 // valor decimal
Valor de B en binario: 10011100
Valor de B en binario luego de aplicarle shift >> 2:
Valor de B en binario: 11100111 // en este caso el bit ms significativo se mantiene para indicar el signo negativo
                                // y los bits que se desplacen hacia la derecha del bit ms significativo 
                                // se completan con unos 1.


-----------------------------------------------------------------------------------------------------------------------------
ejemplos de precedencia de los operandos:


puerto &= ~(1<<6) primero se desplaza un 1 hacia la izquierda 6 posiciones y luego el operando ~ lo convierte en cero. Es resultado se combina mediante el operando & con el contenido del byte del puerto. Aplicndose as una mscara que pone en cero el bit 6 dejando pasar los dems bits. De esta manera se logra un equivalente en assembler de bitclr en la posicin del bit 6.





#define bit_set(bit,puerto) (puerto |= 1<<bit)
#define bit_clr(bit,puerto) (puerto &= ~(1<<bit))



// ejemplo en cdigo
bit_set(0,PORTB); // pone a 1 el bit 0 del puerto B.
bit_clr(0,PORTB); // pone a 0 el bit 0 del puerto B.





-----------------------------------------------------------------------------------------------------------------------------
Cdigo binario en complemento a dos:

En este sistema, los nmeros positivos se representan reservando el bit ms significativo (que debe ser cero) para el signo. Para los nmeros negativos, se utiliza un sistema distinto, denominado complemento a dos, en el que se cambian los bits que seran 0 por 1 y viceversa, y al resultado se le suma uno.
Este sistema sigue reservando el bit ms significativo para el signo, que sigue siendo 1 en los negativos. Por ejemplo, la representacin de 33 y -33 sera:

    +33    0010 0001
         se invierte todo
    -33    1101 1110 
         se le suma 1
         + 0000 0001 
          resultado
           1101 1111   numero -33 en complemento a dos

El hardware necesario para implementar operaciones aritmticas con nmeros representados de este modo es mucho ms sencillo que el del complemento a uno, por lo que es el sistema ms ampliamente utilizado.
-----------------------------------------------------------------------------------------------------------------------------



PARA ROTAR UN BYTE


C language does not specify a rotate operator; however, it does allow shifts. The compiler will detect expressions that implement rotate operations using shift and logical operators and compile them efficiently.

EJEMPLO:
c = (c << 1) | (c >> 7);





